package com.rockcent.wechat.controller;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.OSSObject;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.rockcent.common.common.JsonResult;
import com.rockcent.common.common.RestDoing;
import com.rockcent.common.controller.BaseController;
import com.rockcent.mall.lib.domain.*;
import com.rockcent.mall.lib.domain.enumclass.RefundMethod;
import com.rockcent.mall.lib.domain.enumclass.UploadFileBusinessType;
import com.rockcent.mall.lib.dto.CustomerDto;
import com.rockcent.mall.lib.helper.OrderStatusHelper;
import com.rockcent.mall.lib.repository.*;
import com.rockcent.wechat.Prop;
import com.rockcent.wechat.Routes;
import com.rockcent.wechat.helper.CustomerHelper;
import com.rockcent.wechat.helper.WechatHelper;
import com.rockcent.wechat.service.WxMpPayService;
import me.chanjar.weixin.common.bean.WxJsapiSignature;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.bean.pay.request.WxPayRefundRequest;
import me.chanjar.weixin.mp.bean.pay.result.WxPayRefundResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * Created by DK on 17/2/21.
 * 用户自发退款
 */
@RestController
@RequestMapping(value = Routes.API_PREFIX)
public class InitiativeRefundController extends BaseController {

    private static final Logger log = LoggerFactory.getLogger(InitiativeRefundController.class);

    @Autowired
    private WechatHelper wechatHelper;
    @Autowired
    private WechatConfigRepository wechatConfigRepository;
    @Autowired
    private MallOrderRepository mallOrderRepository;
    @Autowired
    private MerchantOrderRepository merchantOrderRepository;
    @Autowired
    private CustomerHelper customerHelper;
    @Autowired
    private OSSClient ossClient;
    @Autowired
    private Prop prop;
    @Autowired
    private UploadImageFileRepository uploadImageFileRepository;
    @Autowired
    private WxMpPayService wxMpPayService;
    @Autowired
    private MallFundRepository mallFundRepository;
    @Autowired
    private ObjectMapper objectMapper;

    /**
     * @api {get} /api/v2/mall/order/refund 平台订单退款
     * @apiGroup MALL_ORDER_REFUND
     * @apiVersion 1.0.0
     * @apiHeader {String} userToken 用户token
     * @apiHeader {String} domain 请求域名
     *
     * @apiParam {String} url <code>必须参数</code>当前请求url
     * @apiParam {String} orderNum <code>必须参数</code>订单号
     *
     * @apiSuccessExample {json} Success-Response:
     * {
     *     "code" : "1".
     *     "desc" : "成功"
     * }
     */
    @Transactional
    @RequestMapping(value = "/mall/order/refund", method = RequestMethod.GET)
    public JsonResult refund(HttpServletRequest request, String url, String orderNum) {
        CustomerDto dto = customerHelper.getSession(request);
        RestDoing doing = jsonResult -> {
            if (StringUtils.isBlank(orderNum)) {
                jsonResult.errorParam("orderNum 不能为空",log);
                return;
            }
            MallOrder mallOrder = mallOrderRepository.findByOrderNumAndMallIdAndCustomerId(orderNum, dto.getMallId(), dto.getId());
            if (mallOrder == null) {
                jsonResult.remind(MallOrder.REMIND_RECORD_IS_NOT_EXIST,log);;
                return;
            }

            WxMpService wxMpService = wechatHelper.getWxMpService(dto.getMallCustomerDomain());
            //退款订单查询校验
            List<MerchantOrder> merchantOrderList = merchantOrderRepository.findByMallOrderIdAndMallId(mallOrder.getId(), mallOrder.getMallId());
            OrderStatusHelper.SINGLETON.mallOrderRefund(mallOrder, merchantOrderList);
            String refundOrderNum = String.format("%s%d%d", String.format("%03d", mallOrder.getMallId()), 5L, new Date().getTime()); // 生产订单号 5L代表申请退款类型
            String total_fee = mallOrder.getActualAmount().multiply(BigDecimal.valueOf(100)).setScale(0, BigDecimal.ROUND_HALF_DOWN).toString(); //退款金额
            //组装退款数据
            MallWechatConfig config = wechatConfigRepository.queryWechatConfigByDomain(dto.getMallCustomerDomain());
            WxJsapiSignature wxJsapiSignature = wxMpService.createJsapiSignature("http://beta.c.uat.rockcent.com/");
            WxPayRefundRequest wxPayRefundRequest = new WxPayRefundRequest();
            wxPayRefundRequest.setAppid(config.getAppid());
            wxPayRefundRequest.setMchId(config.getMchid());
            wxPayRefundRequest.setNonceStr(wxJsapiSignature.getNoncestr());
            wxPayRefundRequest.setSign(wxJsapiSignature.getSignature());
            wxPayRefundRequest.setTransactionId(mallOrder.getPaymentTransaction());
            wxPayRefundRequest.setOutRefundNo(refundOrderNum);
            wxPayRefundRequest.setTotalFee(Integer.valueOf(total_fee));
            wxPayRefundRequest.setRefundFee(Integer.valueOf(total_fee));
            wxPayRefundRequest.setOpUserId(config.getMchid());
            wxPayRefundRequest.setRefundAccount("REFUND_SOURCE_RECHARGE_FUNDS");//使用可用余额



            //下载商户上传的证书
            OSSObject ossObject = ossClient.getObject(prop.aliyunOssBucketName, config.getWechatCertificatePath());
            //WxPayRefundResult wxPayRefundResult = wxMpPayService.refund(wxPayRefundRequest, ossObject.getObjectContent(), wxMpService);

            //String keyFilePath = "/keyFile/apiclient_cert.p12";
            //Resource fileResource = new ClassPathResource(keyFilePath);
            try {
                WxPayRefundResult wxPayRefundResult = wxMpPayService.refund(wxPayRefundRequest, ossObject.getObjectContent(), wxMpService);

                if (wxPayRefundResult != null && wxPayRefundResult.getReturnCode().equals("SUCCESS") && wxPayRefundResult.getReturnMsg().equals("OK")){
                    String callPayParamsJson = objectMapper.writeValueAsString(wxPayRefundResult);
//                    log.info("======================>callPayParamsJson : {}", callPayParamsJson);
                    if (wxPayRefundResult.getReturnCode().equals("SUCCESS")) {
                        //退款数据返回
                        mallOrder.setRefundOrderNum(refundOrderNum);
                        mallOrder.setRefundAmount(new BigDecimal(wxPayRefundResult.getRefundFee()).divide(BigDecimal.valueOf(100)));
                        //mallOrder.setRefundChannel(RefundChannel.valueOf(wxPayRefundResult.getRefundChannel()));
                        mallOrder.setRefundMethod(RefundMethod.WECHAT);
                        mallOrder.setRefundTransaction(wxPayRefundResult.getRefundId());

                        //平台冻结资金减少
                        MallFund mallFund = mallFundRepository.findOne(mallOrder.getMallFundId());
                        mallFund.setFrozen(mallFund.getFrozen().subtract(mallOrder.getActualAmount()));
                        mallFundRepository.save(mallFund);

                        mallOrderRepository.save(mallOrder);
                        merchantOrderRepository.save(merchantOrderList);
                    }else {
                        jsonResult.errorParam("订单异常 请联系客服",log);
                        return;
                    }
                } else {
                    jsonResult.errorParam("订单异常 请联系客服",log);
                    return;
                }
            }catch (Exception e) {
                jsonResult.errorParam("订单异常 请联系客服",log);
                return;
            }
        };
        return doing.go(request, log);
    }
}
